#!/usr/bin/env python

# Copyright 2011 - 2012 David Selby dave6502@gmail.com

# This file is part of FX Wizard.

# FX Wizard is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# FX Wizard is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with FX Wizard.  If not, see <http://www.gnu.org/licenses/>.



import os, pickle, time, re
import my_mobiler, ocr, log
from exception import WizardExcept


class Engine():

    def __init__(self, my_mobiler_x, my_mobiler_y):


        self.screen_areas = {'main': (0, 0, 246, 404), 'title': (5, 109, 110, 128),
        'reject_message': (6, 134, 239, 201)}

        self.menu_selects = {'menu': (126, 93), 'fx_mobile': (66, 110), 
        'work_list': (66,127), 'history': (66, 144), 'time_sheet': (66, 161), 
        'messenger': (66,178), 'alert': (66,195), 'communication_status': (66, 230)}


        self.alert_selects = {'alert_top': (13, 158), 'tick': (158, 118), 
        'clip_board': (190, 118), 'bin': (211, 118), 'yes': (50, 260),
        'no': (198, 260), 'ok': (125, 260)}

        self.alert_checks = {'alert_all_white': (10, 158, 100, 255, 100), 
        'alert_any_green': (10, 158, 100, 145, 1), 'tick_bground': (151, 118, 13, 57, 100), 
        'clip_board_bground': (189, 118, 10, 57, 100), 'bin_bground': (205, 118, 11, 57, 100), 
        'lhs_yes': (20, 260, 60, 223, 50), 'center_ok': (95, 260, 60, 223, 50)}


        self.WO_areas = {'WO': (5, 283, 155, 297)}

        self.WO_selects = {'WO_top': (13, 158), 'clip_board': (214, 121), 
        'ok': (229, 119)}

        self.WO_old  = ''
        self.WO_dir = True

        self.accel = [1, 2, 5, 15]

        self.mobiler = my_mobiler.MyMobiler(my_mobiler_x, my_mobiler_y)
        self.mobiler.show()
        self.mobiler.grabCtrl()

        self.log = log.Log()







    def minimize(self):

        self.mobiler.hide()





    # ------------------------------------------------------------------------------------------------
    # Methods that drive MyMobiler and perform accepting of alerts in FX
    # ------------------------------------------------------------------------------------------------

    def acceptAlerts(self):

        """
        Perform the magic show ...
        """

        # check for an open work order, will put accept alerts into an infinite
        # loop
        # if self.__checkOpenWO():
        #     raise WizardExcept('wo_open')

        self.__gotoAlerts()
        self.__clearAlerts()


    def __gotoAlerts(self):

        """
        A simple method to get FX to enter the accept alerts screen
        """

        for i in self.accel:

            self.mobiler.click(self.menu_selects['menu'])
            time.sleep(i)

            self.mobiler.click(self.menu_selects['alert'])
            time.sleep(i)

            self.__logEvent('Alerts, Selecting alert screen')

            ocr_img = ocr.OCR(self.mobiler.grabImage(self.screen_areas['title']), True)
            if (ocr_img.has_exact_text('Messages') or ocr_img.has_exact_text('Work Order Preview') or
            self.mobiler.checkLine(self.alert_checks['lhs_yes']) or 
            self.mobiler.checkLine(self.alert_checks['center_ok'])):
                break
        
        else:
            raise WizardExcept('alert_clear_fail')

        self.__logEvent("Alerts, Alert screen selected")


    def __clearAlerts(self):

        """
        A horribly long method to accept all alerts then exit. All sorts of 
        issues, FX GUI lags, clicking white space actually clicks a button, This
        method has caused a lot of pain to this humble developer.
        """

        keep_going = True
        while keep_going:

            time.sleep(2)

            # see if we are in 'messages' screen 
            ocr_img = ocr.OCR(self.mobiler.grabImage(self.screen_areas['title']), True)
            if ocr_img.has_exact_text('Messages'):

                # if top alert line 100% white, no more alerts, quit
                if self.mobiler.checkLine(self.alert_checks['alert_all_white']):

                    self.__logEvent("Alerts, exiting ...")
                    keep_going = False
                    
                # if top alert line has no green, select top alert
                elif not self.mobiler.checkLine(self.alert_checks['alert_any_green']):

                    self.__logEvent("Alerts, About to click top alert")
                    self.mobiler.click(self.alert_selects['alert_top'])

                elif not self.mobiler.checkLine(self.alert_checks['bin_bground']):
                    self.__logEvent("Alerts, About to click 'bin'")
                    self.mobiler.click(self.alert_selects['bin'])
                    
                # if we can't bin it, better open it with the clipboard
                elif not self.mobiler.checkLine(self.alert_checks['clip_board_bground']):
                    self.__logEvent("Alerts, About to click 'clip board'")
                    self.mobiler.click(self.alert_selects['clip_board'])
                    
            # see if we are in 'work order preview'
            elif ocr_img.has_exact_text('Work Order Preview'):

                if not self.mobiler.checkLine(self.alert_checks['tick_bground']):
                    self.__logEvent("Alerts, About to click 'tick'")
                    self.mobiler.click(self.alert_selects['tick'])
                    
            # if all else fails, must be in warning message screen
            else:

                if self.mobiler.checkLine(self.alert_checks['lhs_yes']):

                    # LHS yes can mean two things, best to check ...
                    ocr_img = ocr.OCR(self.mobiler.grabImage(self.screen_areas['reject_message']))
                    if ocr_img.has_exact_text('Rejecting the work order will remove it'):

                        # reject a work order, thats a 'no' then
                        self.__logEvent("Alerts, About to click 'no'")
                        self.mobiler.click(self.alert_selects['no'])

                    else:
                        # message not viewed, delete it ?, thats a 'yes' then
                        self.__logEvent("Alerts, About to click 'yes'")
                        self.mobiler.click(self.alert_selects['yes'])


                # work order removed, thats a 'ok' then
                elif self.mobiler.checkLine(self.alert_checks['center_ok']):
                    self.__logEvent("Alerts, About to click 'ok'")
                    self.mobiler.click(self.alert_selects['ok'])
                    
        self.__logEvent("Alerts, All cleared")

    # ------------------------------------------------------------------------------------------------















    # --------------------------------------------------------------------------------

    # def __checkOpenWO(self):
        
    #     try:
    #         self.__gotoWOList()
    #         return False

    #     except worklistfailWizardExcept('alert_clear_fail'):
    #         return True








# ------------------------------------------------------------------------------
#   WORK LIST ... 
#
# ------------------------------------------------------------------------------

    def workList(self):
        self.__gotoWOList()
        #self.__setupWOList()
        for i in range(200):
            print self.__nextWO()


    def __gotoWOList(self):

        """
        Select the work order list screen and select the first work order, raise 
        an exception if the work list can't be found
        """

        for i in self.accel:

            self.mobiler.click(self.menu_selects['menu'])
            time.sleep(i)

            self.mobiler.click(self.menu_selects['work_list'])
            time.sleep(i)

            ocr_img = ocr.OCR(self.mobiler.grabImage(self.screen_areas['title']), True)

            # preview is open, close it and wait for 'TotalWOs:'
            if ocr_img.has_exact_text('WorkOrderPreview'):
                self.mobiler.click(self.WO_selects['ok'])

                for i in self.accel:
                    time.sleep(i)
                    
                    ocr_img = ocr.OCR(self.mobiler.grabImage(self.screen_areas['title']), True)
                    if ocr_img.raw_text()[:9] == 'TotalWOs:':
                        break

                else:
                    raise WizardExcept('work_list_fail')

            if ocr_img.raw_text()[:9] == 'TotalWOs:':
                break

        else:
            raise WizardExcept('work_list_fail')

        self.mobiler.click(self.WO_selects['WO_top'])


    def __grabWO(self):
        
        """
        Grab a work order by OCR-ing the screen for the currently selected item,
        raise an exception if a work order cannot be found
        """

        for i in self.accel:
            time.sleep(i)

            ocr_img = ocr.OCR(self.mobiler.grabImage(self.WO_areas['WO']))
            txt = ocr_img.raw_text()

            # check for valid work order
            if re.match('^WO#:\d{8}-UK2$', txt):
                WO = txt[4:12]
                break

        else:
            raise WizardExcept('no_WO')

        return WO


    def __nextWO(self):

        """
        Return the next work order number in the work order list, sequence up
        and down the list repeatedly. Note '{UP}' etc are windows escapes !
        """

        WO = self.__grabWO()

        esc = '{DOWN}' if self.WO_dir else '{UP}'
        self.mobiler.sendText(esc)

        if WO == self.WO_old:

            self.WO_dir = not self.WO_dir
            esc = '{DOWN}' if self.WO_dir else '{UP}'

            self.mobiler.sendText(esc)
            self.mobiler.sendText(esc)
            self.mobiler.sendText(esc)
            WO = self.__grabWO()
            self.mobiler.sendText(esc)

        self.WO_old = WO
        return WO

























    def __logEvent(self, text):

        img = self.mobiler.grabImage(self.screen_areas['main'])
        self.log.addComment(text)
        self.log.addImage(img)








#Engine(1000, 300).acceptAlerts()
#Engine().workList()
#Engine(1000, 300).test()
